package com.itheima.java.ai.langchin4j.server.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.java.ai.langchin4j.entity.Appointment;
import com.itheima.java.ai.langchin4j.mapper.AppointmentMapper;
import com.itheima.java.ai.langchin4j.server.AppointmentService;
import com.itheima.java.ai.langchin4j.server.DoctorScheduleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@Service
public class AppointmentServiceImpl extends ServiceImpl<AppointmentMapper, Appointment> implements AppointmentService {
    
    @Autowired
    private AppointmentMapper appointmentMapper;
    
    @Autowired
    private DoctorScheduleService doctorScheduleService;
    
    /**
     * 查询订单是否存在
     * @param appointment
     * @return
     */
    @Override
    public Appointment getOne(Appointment appointment) {
        LambdaQueryWrapper<Appointment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Appointment::getUsername, appointment.getUsername());
        queryWrapper.eq(Appointment::getIdCard, appointment.getIdCard());
        queryWrapper.eq(Appointment::getDepartment, appointment.getDepartment());
        queryWrapper.eq(Appointment::getDate, appointment.getDate());
        queryWrapper.eq(Appointment::getTime, appointment.getTime());
        Appointment appointmentDB = baseMapper.selectOne(queryWrapper);
        return appointmentDB;
    }
    
    @Override
    public Appointment getOne(String username, String idCard, String department, String date, String time, String doctorName) {
        QueryWrapper<Appointment> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username)
                .eq("id_card", idCard)
                .eq("department", department)
                .eq("date", date)
                .eq("time", time)
                .eq("doctor_name", doctorName);
        return this.getOne(queryWrapper);
    }
    
    @Override
    @Transactional
    public Appointment createAppointment(Long userId, Long doctorId, Long scheduleId, LocalDate appointmentDate, String timeSlot, String symptoms) {
        // 检查时间段是否可用
        if (!doctorScheduleService.isTimeSlotAvailable(scheduleId)) {
            throw new RuntimeException("时间段不可用");
        }
        
        // 预订时间段
        if (!doctorScheduleService.bookTimeSlot(scheduleId)) {
            throw new RuntimeException("预订失败");
        }
        
        // 创建预约记录
        Appointment appointment = new Appointment();
        appointment.setUserId(userId);
        appointment.setDoctorId(doctorId);
        appointment.setScheduleId(scheduleId);
        appointment.setAppointmentDate(appointmentDate);
        appointment.setTimeSlot(timeSlot);
        appointment.setSymptoms(symptoms);
        appointment.setStatus(Appointment.Status.PENDING);
        appointment.setCreatedAt(LocalDateTime.now());
        
        this.save(appointment);
        return appointment;
    }
    
    @Override
    public List<Appointment> getUserAppointments(Long userId) {
        return appointmentMapper.findByUserId(userId);
    }
    
    @Override
    public List<Appointment> getDoctorAppointments(Long doctorId) {
        return appointmentMapper.findByDoctorId(doctorId);
    }
    
    @Override
    public List<Appointment> getUserAppointmentsByStatus(Long userId, String status) {
        return appointmentMapper.findByUserIdAndStatus(userId, status);
    }
    
    @Override
    public List<Appointment> getDoctorAppointmentsByDate(Long doctorId, LocalDate date) {
        return appointmentMapper.findByDoctorIdAndDate(doctorId, date);
    }
    
    @Override
    public boolean updateAppointmentStatus(Long appointmentId, String status) {
        return appointmentMapper.updateStatus(appointmentId, status) > 0;
    }
    
    @Override
    @Transactional
    public boolean cancelAppointment(Long appointmentId, Long userId) {
        Appointment appointment = this.getById(appointmentId);
        if (appointment == null || !appointment.getUserId().equals(userId)) {
            return false;
        }
        
        // 释放时间段
        if (appointment.getScheduleId() != null) {
            doctorScheduleService.cancelTimeSlot(appointment.getScheduleId());
        }
        
        // 更新预约状态
        return updateAppointmentStatus(appointmentId, Appointment.Status.CANCELLED.name());
    }
    
    @Override
    public boolean confirmAppointment(Long appointmentId) {
        return updateAppointmentStatus(appointmentId, Appointment.Status.CONFIRMED.name());
    }
}